package com.yuliang.ai.request;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yuliang.ai.domain.Vo.ChatVo;
import com.yuliang.ai.websocket.WebSocketServer;
import com.yuliang.utils.util.BeanUtils;
import com.yuliang.utils.util.RedisUtils;
import com.yuliang.utils.util.StringUtils;
import com.yuliang.utils.util.UnicodeConvert;
import io.socket.client.IO;
import io.socket.client.Socket;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author Huangkai
 */
@Slf4j
@Component
public class SocketIOClientLaunch {

    @Value("${spring.chartGpt.baichuan.url}")
    private String url;

    public static Socket socket = null;

    public void clientSocketIo(){
        try {
            IO.Options options = new IO.Options();
            options.transports = new String[]{"websocket"};
            //失败重试次数
            options.reconnectionAttempts = 10;
            //失败重连的时间间隔
            options.reconnectionDelay = 1000;
            //连接超时时间(ms)
            options.timeout = 500;;
            socket = IO.socket(url, options);
            //监听到服务器消息
            socket.on("socket_message",
                    objects -> {
                        JSONObject resultJSON = new JSONObject();
                        String arrayStr = Arrays.toString(objects);
                        JSONArray jsonArray = JSONArray.parseArray(arrayStr);
                        JSONObject jsonObject = jsonArray.getJSONObject(0);
                        log.info("结果{}", jsonObject);
                        if(jsonObject.containsKey("msg_type")){
                            if(jsonObject.getInteger("msg_type") == 2){                               String keywords = jsonObject.getString("kw");
                                log.info("关键词{}", keywords);
                            }
                            if(jsonObject.getInteger("msg_type") == 3){
                                Integer chatId = jsonObject.getInteger("chatId");
                                resultJSON.put("chatId", chatId);
                                Integer chatAnsId = jsonObject.getInteger("chatAnsId");
                                resultJSON.put("chatAnsId", chatAnsId);
                                String key = "" + chatId + chatAnsId;
                                //保存了会话作为key，则通过会话信息获取到设备信息
                                if (RedisUtils.hasKey(key)){
                                    String contentInfo = RedisUtils.get(key);
                                    ChatVo chatVo = JSONObject.parseObject(contentInfo, ChatVo.class);
                                    String collectionKey = chatVo.getDeviceId() + chatVo.getUserId() + chatVo.getHumanIdentifyId() + "result";
                                    String content = null;
                                    String contentUnicode = jsonObject.getString("res_content");
                                    Integer isEnd = jsonObject.getInteger("is_end");
                                    if(null != contentUnicode){
                                        content = UnicodeConvert.unicodeDecode(contentUnicode);
                                        //从redis中获取收集的结果
                                        if(RedisUtils.hasKey(collectionKey)){
                                            content = (RedisUtils.get(collectionKey) + content);
                                        }
                                        RedisUtils.setEx(collectionKey, content, 5, TimeUnit.MINUTES);
                                    }
                                    resultJSON.put("isEnd", isEnd);
                                    resultJSON.put("content", content);
                                    //表示结束
                                    if(isEnd == 1){
                                        //装进去视频信息
                                        List<String> videoPathList =new ArrayList<>();
                                        if(jsonObject.containsKey("url")){
                                            String url = jsonObject.getString("url");
                                            if(StringUtils.isNotEmpty(url)){
                                                videoPathList.add(url);
                                            }
                                        }
                                        resultJSON.put("videoPathList", videoPathList);
                                        if(jsonObject.containsKey("img")){
                                            List<String> imgList = jsonObject.getJSONArray("img").toJavaList(String.class);
                                            resultJSON.put("imgList", imgList);
                                        }

                                    }
                                    if(content.length() >= 30 || isEnd == 1){
                                        log.info("传输到客户端的信息{}", resultJSON);
                                        WebSocketServer messagePushWebSocket = BeanUtils.getBean("webSocketServer");
                                        messagePushWebSocket.sendOneMessage(chatVo.getDeviceId(), resultJSON);
                                        //发送结束，删除redis
                                        RedisUtils.delete(collectionKey);
                                    }
                                }
                            }
                        }
            });
            socket.on(Socket.EVENT_RECONNECT, objects -> log.info("client:{}", "重连成功"));
            socket.on(Socket.EVENT_CONNECT, objects -> log.info("client: {}", "连接成功"));
            socket.on(Socket.EVENT_PONG, objects -> log.info("client: {}", "收到Pong"));
            socket.on(Socket.EVENT_PING, objects -> log.info("client: {}", "发送ping"));
            socket.on(Socket.EVENT_CONNECTING, objects -> log.info("client: ", "连接中"));
            socket.on(Socket.EVENT_CONNECT_TIMEOUT, objects -> log.info("client: " + "连接超时"));
            socket.on(Socket.EVENT_CONNECT_ERROR, objects -> log.info("client: " + "连接失败"));
            socket.connect();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

}